@@ -33,7 +33,7 @@ class LensmanIncomeExpensesInfoAdmin(admin.ModelAdmin):  | 
            ||
| 33 | 33 | 
                 | 
            
| 34 | 34 | 
                class UserInfoAdmin(admin.ModelAdmin):  | 
            
| 35 | 35 | 
                     readonly_fields = ('user_id', )
               | 
            
| 36 | 
                -    list_display = ('user_id', 'user_from', 'username', 'wx_uid', 'name', 'sex', 'phone', 'location', 'user_status', 'status', 'created_at', 'updated_at')
               | 
            |
| 36 | 
                +    list_display = ('user_id', 'user_from', 'username', 'wx_uid', 'name', 'sex', 'nickname', 'phone', 'location', 'user_status', 'status', 'created_at', 'updated_at')
               | 
            |
| 37 | 37 | 
                     search_fields = ('name', 'phone', 'location')
               | 
            
| 38 | 38 | 
                     list_filter = ('user_from', 'sex', 'user_status', 'status')
               | 
            
| 39 | 39 | 
                 | 
            
                @@ -0,0 +1,19 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import models, migrations  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('account', '0009_auto_20160428_1410'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.AddField(  | 
            |
| 15 | 
                + model_name='userinfo',  | 
            |
| 16 | 
                + name='uuid',  | 
            |
| 17 | 
                + field=models.CharField(max_length=255, blank=True, help_text='\u901a\u7528\u552f\u4e00\u8bc6\u522b\u7801 (Universally Unique Identifier)', null=True, verbose_name='uuid', db_index=True),  | 
            |
| 18 | 
                + ),  | 
            |
| 19 | 
                + ]  | 
            
                @@ -127,6 +127,7 @@ class UserInfo(CreateUpdateMixin):  | 
            ||
| 127 | 127 | 
                user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True, unique=True)  | 
            
| 128 | 128 | 
                 | 
            
| 129 | 129 | 
                user_from = models.IntegerField(_(u'user_from'), choices=USER_FROM, default=APP_USER, help_text=u'用户来源')  | 
            
| 130 | 
                + uuid = models.CharField(_(u'uuid'), max_length=255, blank=True, null=True, help_text=u'通用唯一识别码 (Universally Unique Identifier)', db_index=True)  | 
            |
| 130 | 131 | 
                # APP 创建用户  | 
            
| 131 | 132 | 
                username = models.CharField(_(u'username'), max_length=255, blank=True, null=True, help_text=u'用户用户名', db_index=True, unique=True)  | 
            
| 132 | 133 | 
                password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'用户密码')  | 
            
                @@ -1,7 +1,6 @@  | 
            ||
| 1 | 1 | 
                # -*- coding: utf-8 -*-  | 
            
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                from curtail_uuid import CurtailUUID  | 
            
| 4 | 
                -from django.conf import settings  | 
            |
| 5 | 4 | 
                from django.contrib.auth.hashers import check_password, make_password  | 
            
| 6 | 5 | 
                from django.contrib.auth.models import Group, User  | 
            
| 7 | 6 | 
                from django.http import JsonResponse  | 
            
                @@ -10,9 +9,12 @@ from TimeConvert import TimeConvert as tc  | 
            ||
| 10 | 9 | 
                 | 
            
| 11 | 10 | 
                from account.models import LensmanInfo, UserInfo, UserLoginLogInfo  | 
            
| 12 | 11 | 
                from account.serializers import GroupSerializer, LensmanInfoSerializer, UserInfoSerializer, UserSerializer  | 
            
| 12 | 
                +from operation.models import GuestEntranceControlInfo  | 
            |
| 13 | 13 | 
                from utils.error.errno_utils import LensmanStatusCode, UserStatusCode  | 
            
| 14 | 14 | 
                from utils.error.response_utils import response  | 
            
| 15 | 15 | 
                from utils.ip_utils import ip_addr  | 
            
| 16 | 
                +from utils.redis.rversion import get_guest_entrance_control  | 
            |
| 17 | 
                +from utils.version_utils import is_version_match  | 
            |
| 16 | 18 | 
                 | 
            
| 17 | 19 | 
                 | 
            
| 18 | 20 | 
                # curl -X POST -F username=xxxxxxx -F password=xxxxxxx http://api.pai.ai/login  | 
            
                @@ -209,10 +211,41 @@ def wx_authorize_api(request):  | 
            ||
| 209 | 211 | 
                 | 
            
| 210 | 212 | 
                 | 
            
| 211 | 213 | 
                def guest_login_api(request):  | 
            
| 212 | 
                - try:  | 
            |
| 213 | 
                - user = UserInfo.objects.get(user_id=settings.GUEST_USER_ID)  | 
            |
| 214 | 
                - except UserInfo.DoesNotExist:  | 
            |
| 215 | 
                - return response(UserStatusCode.GUEST_NOT_FOUND)  | 
            |
| 214 | 
                + """ 游客登录 """  | 
            |
| 215 | 
                + gen = get_guest_entrance_control()  | 
            |
| 216 | 
                +  | 
            |
| 217 | 
                + # 是否配置游客入口控制信息  | 
            |
| 218 | 
                + if not gen:  | 
            |
| 219 | 
                + return response(UserStatusCode.GUEST_NOT_ALLOWED)  | 
            |
| 220 | 
                +  | 
            |
| 221 | 
                + # 平台校验  | 
            |
| 222 | 
                +    platform = gen.get('platform', '')
               | 
            |
| 223 | 
                + if request.Android:  | 
            |
| 224 | 
                + if platform not in [GuestEntranceControlInfo.ADR, GuestEntranceControlInfo.BOTH]:  | 
            |
| 225 | 
                + return response(UserStatusCode.GUEST_NOT_ALLOWED)  | 
            |
| 226 | 
                + else:  | 
            |
| 227 | 
                + if platform not in [GuestEntranceControlInfo.IOS, GuestEntranceControlInfo.BOTH]:  | 
            |
| 228 | 
                + return response(UserStatusCode.GUEST_NOT_ALLOWED)  | 
            |
| 229 | 
                +  | 
            |
| 230 | 
                + # 版本校验  | 
            |
| 231 | 
                + if not is_version_match(request, gen):  | 
            |
| 232 | 
                + return response(UserStatusCode.GUEST_NOT_ALLOWED)  | 
            |
| 233 | 
                +  | 
            |
| 234 | 
                + # 通用唯一识别码 (Universally Unique Identifier)  | 
            |
| 235 | 
                +    uuid = request.POST.get('uuid', '')
               | 
            |
| 236 | 
                + # 游客字段  | 
            |
| 237 | 
                +    fields = {
               | 
            |
| 238 | 
                + 'user_id': CurtailUUID.uuid(UserInfo, 'user_id'),  | 
            |
| 239 | 
                + 'user_from': UserInfo.GUEST_USER,  | 
            |
| 240 | 
                + 'uuid': uuid,  | 
            |
| 241 | 
                + 'nickname': u'游客',  | 
            |
| 242 | 
                + 'user_status': UserInfo.ACTIVATED,  | 
            |
| 243 | 
                + }  | 
            |
| 244 | 
                + # 若 uuid 存在,则 get_or_create,否则 create  | 
            |
| 245 | 
                + if uuid:  | 
            |
| 246 | 
                + user, created = UserInfo.objects.get_or_create(user_from=UserInfo.GUEST_USER, uuid=uuid, defaults=fields)  | 
            |
| 247 | 
                + else:  | 
            |
| 248 | 
                + user = UserInfo.objects.create(**fields)  | 
            |
| 216 | 249 | 
                 | 
            
| 217 | 250 | 
                     return JsonResponse({
               | 
            
| 218 | 251 | 
                'status': 200,  | 
            
                @@ -2,7 +2,8 @@  | 
            ||
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                from django.contrib import admin  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 
                -from operation.models import FeedbackInfo, LatestAppInfo, SplashInfo  | 
            |
| 5 | 
                +from operation.models import FeedbackInfo, GuestEntranceControlInfo, LatestAppInfo, SplashInfo  | 
            |
| 6 | 
                +from utils.redis.rversion import set_guest_entrance_control  | 
            |
| 6 | 7 | 
                 | 
            
| 7 | 8 | 
                 | 
            
| 8 | 9 | 
                class LatestAppInfoAdmin(admin.ModelAdmin):  | 
            
                @@ -17,6 +18,17 @@ class FeedbackInfoAdmin(admin.ModelAdmin):  | 
            ||
| 17 | 18 | 
                     list_display = ('user_id', 'feedback', 'status', 'created_at', 'updated_at')
               | 
            
| 18 | 19 | 
                 | 
            
| 19 | 20 | 
                 | 
            
| 21 | 
                +class GuestEntranceControlInfoAdmin(admin.ModelAdmin):  | 
            |
| 22 | 
                +    list_display = ('platform', 'min_adr', 'max_adr', 'min_ios', 'max_ios', 'status', 'created_at', 'updated_at')
               | 
            |
| 23 | 
                +  | 
            |
| 24 | 
                + def save_model(self, request, obj, form, change):  | 
            |
| 25 | 
                + obj.save()  | 
            |
| 26 | 
                +  | 
            |
| 27 | 
                + # 设置游客入口控制  | 
            |
| 28 | 
                + set_guest_entrance_control(obj)  | 
            |
| 29 | 
                +  | 
            |
| 30 | 
                +  | 
            |
| 20 | 31 | 
                admin.site.register(LatestAppInfo, LatestAppInfoAdmin)  | 
            
| 21 | 32 | 
                admin.site.register(SplashInfo, SplashInfoAdmin)  | 
            
| 22 | 33 | 
                admin.site.register(FeedbackInfo, FeedbackInfoAdmin)  | 
            
| 34 | 
                +admin.site.register(GuestEntranceControlInfo, GuestEntranceControlInfoAdmin)  | 
            
                @@ -0,0 +1,32 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import models, migrations  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('operation', '0003_feedbackinfo'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.CreateModel(  | 
            |
| 15 | 
                + name='GuestEntranceControlInfo',  | 
            |
| 16 | 
                + fields=[  | 
            |
| 17 | 
                +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
               | 
            |
| 18 | 
                +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')),
               | 
            |
| 19 | 
                +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
               | 
            |
| 20 | 
                +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
               | 
            |
| 21 | 
                +                ('platform', models.IntegerField(default=0, help_text='\u652f\u6301\u5e73\u53f0', db_index=True, verbose_name='plat', choices=[(0, '\u5168\u5e73\u53f0'), (1, 'Android'), (2, 'iOS')])),
               | 
            |
| 22 | 
                +                ('min_adr', models.CharField(help_text='Adr \u6700\u4f4e\u7248\u672c', max_length=255, null=True, verbose_name='min_adr', blank=True)),
               | 
            |
| 23 | 
                +                ('min_ios', models.CharField(help_text='iOS \u6700\u4f4e\u7248\u672c', max_length=255, null=True, verbose_name='min_ios', blank=True)),
               | 
            |
| 24 | 
                +                ('max_adr', models.CharField(help_text='Adr \u6700\u9ad8\u7248\u672c', max_length=255, null=True, verbose_name='max_adr', blank=True)),
               | 
            |
| 25 | 
                +                ('max_ios', models.CharField(help_text='iOS \u6700\u9ad8\u7248\u672c', max_length=255, null=True, verbose_name='max_ios', blank=True)),
               | 
            |
| 26 | 
                + ],  | 
            |
| 27 | 
                +            options={
               | 
            |
| 28 | 
                + 'verbose_name': 'guestentrancecontrolinfo',  | 
            |
| 29 | 
                + 'verbose_name_plural': 'guestentrancecontrolinfo',  | 
            |
| 30 | 
                + },  | 
            |
| 31 | 
                + ),  | 
            |
| 32 | 
                + ]  | 
            
                @@ -8,7 +8,7 @@ from django.conf import settings  | 
            ||
| 8 | 8 | 
                from django.db import models  | 
            
| 9 | 9 | 
                from django.utils.translation import ugettext_lazy as _  | 
            
| 10 | 10 | 
                 | 
            
| 11 | 
                -from pai2.basemodels import CreateUpdateMixin  | 
            |
| 11 | 
                +from pai2.basemodels import CreateUpdateMixin, PlatformMixin, VersionMixin  | 
            |
| 12 | 12 | 
                 | 
            
| 13 | 13 | 
                 | 
            
| 14 | 14 | 
                def upload_path(instance, old_filename):  | 
            
                @@ -38,14 +38,13 @@ class LatestAppInfo(CreateUpdateMixin):  | 
            ||
| 38 | 38 | 
                def final_latest_url(self):  | 
            
| 39 | 39 | 
                         return self.latest_url or u'{}{}'.format(settings.DOMAIN, self.latest_app and self.latest_app.url)
               | 
            
| 40 | 40 | 
                 | 
            
| 41 | 
                - def _data(self):  | 
            |
| 41 | 
                + @property  | 
            |
| 42 | 
                + def data(self):  | 
            |
| 42 | 43 | 
                         return {
               | 
            
| 43 | 44 | 
                'latest_version': self.latest_version,  | 
            
| 44 | 45 | 
                'latest_url': self.final_latest_url,  | 
            
| 45 | 46 | 
                }  | 
            
| 46 | 47 | 
                 | 
            
| 47 | 
                - data = property(_data)  | 
            |
| 48 | 
                -  | 
            |
| 49 | 48 | 
                 | 
            
| 50 | 49 | 
                class SplashInfo(CreateUpdateMixin):  | 
            
| 51 | 50 | 
                splash_image = models.ImageField(_(u'splash_image'), upload_to=upload_path, blank=True, null=True, help_text=u'启动页面图片')  | 
            
                @@ -63,15 +62,14 @@ class SplashInfo(CreateUpdateMixin):  | 
            ||
| 63 | 62 | 
                def splash_image_url(self):  | 
            
| 64 | 63 | 
                return self.splash_image and (settings.DOMAIN + self.splash_image.url)  | 
            
| 65 | 64 | 
                 | 
            
| 66 | 
                - def _data(self):  | 
            |
| 65 | 
                + @property  | 
            |
| 66 | 
                + def data(self):  | 
            |
| 67 | 67 | 
                         return {
               | 
            
| 68 | 68 | 
                'splash_image_url': self.splash_image_url,  | 
            
| 69 | 69 | 
                'spalash_image_airtime': self.spalash_image_airtime,  | 
            
| 70 | 70 | 
                'spalash_image_deadline': self.spalash_image_deadline,  | 
            
| 71 | 71 | 
                }  | 
            
| 72 | 72 | 
                 | 
            
| 73 | 
                - data = property(_data)  | 
            |
| 74 | 
                -  | 
            |
| 75 | 73 | 
                 | 
            
| 76 | 74 | 
                class FeedbackInfo(CreateUpdateMixin):  | 
            
| 77 | 75 | 
                user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识')  | 
            
                @@ -83,3 +81,23 @@ class FeedbackInfo(CreateUpdateMixin):  | 
            ||
| 83 | 81 | 
                 | 
            
| 84 | 82 | 
                def __unicode__(self):  | 
            
| 85 | 83 | 
                         return u'{0.pk}'.format(self)
               | 
            
| 84 | 
                +  | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                +class GuestEntranceControlInfo(CreateUpdateMixin, PlatformMixin, VersionMixin):  | 
            |
| 87 | 
                +  | 
            |
| 88 | 
                + class Meta:  | 
            |
| 89 | 
                +        verbose_name = _('guestentrancecontrolinfo')
               | 
            |
| 90 | 
                +        verbose_name_plural = _('guestentrancecontrolinfo')
               | 
            |
| 91 | 
                +  | 
            |
| 92 | 
                + def __unicode__(self):  | 
            |
| 93 | 
                +        return u'{0.pk}'.format(self)
               | 
            |
| 94 | 
                +  | 
            |
| 95 | 
                + @property  | 
            |
| 96 | 
                + def data(self):  | 
            |
| 97 | 
                +        return {
               | 
            |
| 98 | 
                + 'platform': self.platform,  | 
            |
| 99 | 
                + 'min_adr': self.min_adr,  | 
            |
| 100 | 
                + 'min_ios': self.min_ios,  | 
            |
| 101 | 
                + 'max_adr': self.max_adr,  | 
            |
| 102 | 
                + 'max_ios': self.max_ios,  | 
            |
| 103 | 
                + }  | 
            
                @@ -3,6 +3,8 @@  | 
            ||
| 3 | 3 | 
                from django.db import models  | 
            
| 4 | 4 | 
                from django.utils.translation import ugettext_lazy as _  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                +from utils.version_utils import is_version_match  | 
            |
| 7 | 
                +  | 
            |
| 6 | 8 | 
                 | 
            
| 7 | 9 | 
                class CreateUpdateMixin(models.Model):  | 
            
| 8 | 10 | 
                status = models.BooleanField(_(u'status'), default=True, help_text=_(u'状态'), db_index=True)  | 
            
                @@ -11,3 +13,38 @@ class CreateUpdateMixin(models.Model):  | 
            ||
| 11 | 13 | 
                 | 
            
| 12 | 14 | 
                class Meta:  | 
            
| 13 | 15 | 
                abstract = True  | 
            
| 16 | 
                +  | 
            |
| 17 | 
                +  | 
            |
| 18 | 
                +class PlatformMixin(models.Model):  | 
            |
| 19 | 
                + BOTH = 0  | 
            |
| 20 | 
                + ADR = 1  | 
            |
| 21 | 
                + IOS = 2  | 
            |
| 22 | 
                +  | 
            |
| 23 | 
                + SUPPORT_PLATFORM = (  | 
            |
| 24 | 
                + (BOTH, u'全平台'),  | 
            |
| 25 | 
                + (ADR, u'Android'),  | 
            |
| 26 | 
                + (IOS, u'iOS'),  | 
            |
| 27 | 
                + )  | 
            |
| 28 | 
                +  | 
            |
| 29 | 
                + platform = models.IntegerField(_(u'plat'), choices=SUPPORT_PLATFORM, default=BOTH, help_text=u'支持平台', db_index=True)  | 
            |
| 30 | 
                +  | 
            |
| 31 | 
                + class Meta:  | 
            |
| 32 | 
                + abstract = True  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                +  | 
            |
| 35 | 
                +class VersionMixin(models.Model):  | 
            |
| 36 | 
                + min_adr = models.CharField(_(u'min_adr'), max_length=255, blank=True, null=True, help_text=u'Adr 最低版本')  | 
            |
| 37 | 
                + min_ios = models.CharField(_(u'min_ios'), max_length=255, blank=True, null=True, help_text=u'iOS 最低版本')  | 
            |
| 38 | 
                + max_adr = models.CharField(_(u'max_adr'), max_length=255, blank=True, null=True, help_text=u'Adr 最高版本')  | 
            |
| 39 | 
                + max_ios = models.CharField(_(u'max_ios'), max_length=255, blank=True, null=True, help_text=u'iOS 最高版本')  | 
            |
| 40 | 
                +  | 
            |
| 41 | 
                + def version_match(self, request):  | 
            |
| 42 | 
                +        return is_version_match(request, {
               | 
            |
| 43 | 
                + 'min_adr': self.min_adr,  | 
            |
| 44 | 
                + 'min_ios': self.min_ios,  | 
            |
| 45 | 
                + 'max_adr': self.max_adr,  | 
            |
| 46 | 
                + 'max_ios': self.max_ios,  | 
            |
| 47 | 
                + })  | 
            |
| 48 | 
                +  | 
            |
| 49 | 
                + class Meta:  | 
            |
| 50 | 
                + abstract = True  | 
            
                @@ -64,6 +64,7 @@ MIDDLEWARE_CLASSES = (  | 
            ||
| 64 | 64 | 
                'django.contrib.messages.middleware.MessageMiddleware',  | 
            
| 65 | 65 | 
                'django.middleware.clickjacking.XFrameOptionsMiddleware',  | 
            
| 66 | 66 | 
                'django.middleware.security.SecurityMiddleware',  | 
            
| 67 | 
                + 'detect.middleware.UserAgentDetectionMiddleware',  | 
            |
| 67 | 68 | 
                )  | 
            
| 68 | 69 | 
                 | 
            
| 69 | 70 | 
                 MIDDLEWARE_CLASSES += ('multidomain.middleware.DomainMiddleware', )
               | 
            
                @@ -254,6 +255,11 @@ GROUP_PER_PAGE = 20 # 群组每页数量  | 
            ||
| 254 | 255 | 
                # 游客设置  | 
            
| 255 | 256 | 
                GUEST_USER_ID = 'guest'  | 
            
| 256 | 257 | 
                 | 
            
| 258 | 
                +# 版本设置  | 
            |
| 259 | 
                +MIN_VERSION = '0.0.0'  | 
            |
| 260 | 
                +MAX_VERSION = '999.999.999'  | 
            |
| 261 | 
                +CURRENT_VERSION = '1.0.0'  | 
            |
| 262 | 
                +  | 
            |
| 257 | 263 | 
                # 价格设置  | 
            
| 258 | 264 | 
                LENSMAN_PHOTO_HAGGLE_MAX_TIMES = 3 # 摄影师照片最大砍价次数  | 
            
| 259 | 265 | 
                 | 
            
                @@ -1,10 +1,11 @@  | 
            ||
| 1 | 1 | 
                CodeConvert==2.0.4  | 
            
| 2 | 2 | 
                Django==1.8.4  | 
            
| 3 | 3 | 
                MySQL-python==1.2.5  | 
            
| 4 | 
                -TimeConvert==1.1.6  | 
            |
| 4 | 
                +TimeConvert==1.2.0  | 
            |
| 5 | 5 | 
                cryptography==1.2.1  | 
            
| 6 | 6 | 
                django-curtail-uuid==1.0.0  | 
            
| 7 | 
                -django-logit==1.0.0  | 
            |
| 7 | 
                +django-detect==1.0.3  | 
            |
| 8 | 
                +django-logit==1.0.2  | 
            |
| 8 | 9 | 
                django-multidomain==1.1.4  | 
            
| 9 | 10 | 
                django-shortuuidfield==0.1.3  | 
            
| 10 | 11 | 
                djangorestframework==3.3.1  | 
            
                @@ -17,4 +18,5 @@ pytz==2015.7  | 
            ||
| 17 | 18 | 
                redis==2.10.5  | 
            
| 18 | 19 | 
                shortuuid==0.4.2  | 
            
| 19 | 20 | 
                uWSGI==2.0.11.1  | 
            
| 20 | 
                -wechatpy==1.2.6  | 
            |
| 21 | 
                +versions==0.10.0  | 
            |
| 22 | 
                +wechatpy==1.2.8  | 
            
                @@ -26,7 +26,7 @@ class UserStatusCode(BaseStatusCode):  | 
            ||
| 26 | 26 | 
                USER_PASSWORD_ERROR = StatusCodeField(400102, u'User Password Error', description=u'用户密码错误')  | 
            
| 27 | 27 | 
                USERNAME_HAS_REGISTERED = StatusCodeField(400103, u'Username Has Registered', description=u'用户名已注册')  | 
            
| 28 | 28 | 
                 | 
            
| 29 | 
                - GUEST_NOT_FOUND = StatusCodeField(400111, u'Guest Not Found', description=u'游客不存在')  | 
            |
| 29 | 
                + GUEST_NOT_ALLOWED = StatusCodeField(400111, u'Guest Not ALLOWED', description=u'游客登录不允许')  | 
            |
| 30 | 30 | 
                 | 
            
| 31 | 31 | 
                 | 
            
| 32 | 32 | 
                class PhotoStatusCode(BaseStatusCode):  | 
            
                @@ -26,3 +26,6 @@ LENSMAN_PHOTO_ORDER_RECORD = 'lensman:photo:order:record:%s:%s' # STRING,摄  | 
            ||
| 26 | 26 | 
                # 系统消息相关  | 
            
| 27 | 27 | 
                SYSTEM_MESSAGE_READ_INFO = 'system:message:read:info:%s' # STRING,系统消息读取信息,user_id  | 
            
| 28 | 28 | 
                SYSTEM_MESSAGE_DELETED_INFO = 'system:message:deleted:info:%s' # STRING,系统消息删除信息,user_id  | 
            
| 29 | 
                +  | 
            |
| 30 | 
                +# 游客入口相关  | 
            |
| 31 | 
                +GUEST_ENTRANCE_CONTROL_INFO = 'guest:entrance:control:info' # STRING,游客入口控制信息  | 
            
                @@ -0,0 +1,24 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +import json  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.conf import settings  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +from utils.redis.rkeys import GUEST_ENTRANCE_CONTROL_INFO  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                +r = settings.REDIS_CACHE  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                +# 游客入口控制相关  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +  | 
            |
| 16 | 
                +def set_guest_entrance_control(gen):  | 
            |
| 17 | 
                + """ 设置游客入口控制 """  | 
            |
| 18 | 
                + r.set(GUEST_ENTRANCE_CONTROL_INFO, json.dumps(gen.data))  | 
            |
| 19 | 
                + return gen.data  | 
            |
| 20 | 
                +  | 
            |
| 21 | 
                +  | 
            |
| 22 | 
                +def get_guest_entrance_control():  | 
            |
| 23 | 
                + """ 获取游客入口控制 """  | 
            |
| 24 | 
                +    return json.loads(r.get(GUEST_ENTRANCE_CONTROL_INFO) or '{}')
               | 
            
                @@ -0,0 +1,10 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from django.conf import settings  | 
            |
| 4 | 
                +from versions import Version  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +def is_version_match(request, vers={}):
               | 
            |
| 8 | 
                +    minv, maxv = (vers.get('min_adr', ''), vers.get('max_adr', '')) if request.Android else (vers.get('min_ios', ''), vers.get('max_ios', ''))
               | 
            |
| 9 | 
                + return Version.parse(minv or settings.MIN_VERSION) <= Version.parse(  | 
            |
| 10 | 
                +        request.REQUEST.get('version', settings.CURRENT_VERSION)) <= Version.parse(maxv or settings.MAX_VERSION)
               |